<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Class</title>
</head>

<body>
  <script type="text/javascript">
    /**
     * 总结：
     *  1、类中的构造器不是必写，要对实例进行一些初始化操作，如添加指定属性时才写
     *  2、如果A类继承了B类，A类中写了构造器，那么A类构造器中的super是必须调用的
     *  3、类中定义的方法，都是放在了类的原型对象上，供实例对象使用
     */
    class Person {
      // 构造方法
      constructor(name, age) {
        this.name = name
        this.age = age
      }
      // 一般方法
      speak() {
        //通过Person实例调用speak， this就是Person实例
        console.log(`我叫${this.name}，今年${this.age}岁`);
      }
    }

    class Student extends Person {
      constructor(name, age, grade) {
        // super必须在所有之前
        super(name, age)
        this.grade = grade;
      }
      // 重写从父类继承的方法
      speak() {
        //通过Person实例调用speak， this就是Person实例
        console.log(`我叫${this.name}，今年${this.age}岁,今年${this.grade}`);
      }
      study() {
        console.log("我学习很努力");
      }
    }

    class Car {
      constructor(name,price){
        this.name = name
        this.price = price
        // this.wheel = 4
      }
      // 类中可以直接写赋值语句，如下代码的含义是：给给Car的实例对象添加一个属性，名为a，值为1
      a = 1
      wheel = 4
    }

    const c1 = new Car("宝马",212)
    console.log(c1); 
    /**
     {
          "a": 1,
          "wheel": 4,
          "name": "宝马",
          "price": 212
      }
     */ 
    

    // const p1 = new Person("tom", 12)
    // const p2 = new Person("jack", 14)

    // console.log(p1);
    // console.log(p2);

    // p1.speak()
    // p2.speak()
    // p1.speak.call({a:1,b:2}) //修改this调用指向


    // const s1 = new Student("tom", 12,'高一')
    // console.log(s1);
    // s1.speak()
    // s1.study()
  </script>
</body>

</html>
